package com.dingding.order.core.pay.biz.impl;

import java.math.BigDecimal;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.Useraccount;
import com.dingding.common.core.beans.Userintegral;
import com.dingding.facade.account.user.service.IUserAccountService;
import com.dingding.facade.user.facade.passanger.coupon.IUserCouponFacade;
import com.dingding.order.code.pay.GoToPayStatus;
import com.dingding.order.core.common.IUserFormalOrderDao;
import com.dingding.order.core.common.IUserOrderDao;
import com.dingding.order.core.common.IUserTaxiOrderDao;
import com.dingding.order.core.pay.biz.IGoToPayService;
import com.dingding.order.dto.pay.gotopay.ReqGoToPay;
import com.dingding.order.dto.pay.gotopay.ResGoToPay;
import com.dingding.order.dto.pay.paymoney.GetThirdPayAndAccountDto;
import com.dingding.order.processer.ProcesserFactory;

/**
 * @Description:去支付订单
 * @author fengshuonan
 * @date 2016年6月3日 上午11:46:11
 */
@Service("goToPayService")
public class GoToPayServiceImpl extends AbstractResponse<ResGoToPay, ReqGoToPay> implements IGoToPayService {

	@Resource(name = "userAccountService")
	private IUserAccountService userAccountService; // 用户账户service

	@Resource(name = "userOrderCommonDao")
	private IUserOrderDao userOrderDao;

	@Resource(name = "userTaxiOrderDao")
	private IUserTaxiOrderDao userTaxiOrderDao;

	@Resource(name = "userFormalOrderDao")
	private IUserFormalOrderDao userFormalOrderDao;

	@Resource(name = "processerFactory")
	private ProcesserFactory processerFactory;

	@Resource(name = "_userCouponFacade")
	private IUserCouponFacade userCouponFacade;

	/**
	 * 
	 * @Description: 去支付接口
	 * @author fengshuonan
	 * @return String 返回json
	 * @since 2.3.0
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String goToPay(String requestJson) {

		ReqGoToPay reqGoToPay = super.parseRequestJson(requestJson);

		ResponseEntity<ResGoToPay> responseEntity = new ResponseEntity<ResGoToPay>();
		ResGoToPay resGoToPay = new ResGoToPay();
		responseEntity.setResponseBody(resGoToPay);

		// 验证参数是否为空
		if (!super.validateParam(responseEntity, reqGoToPay)) {
			return super.responseBeanToJson(responseEntity);
		}

		// 获取账户余额和账户积分
		if (!this.getUserAccountMoney(reqGoToPay, responseEntity)) {
			return super.responseBeanToJson(responseEntity);
		}

		// 获取订单状态
		if (!this.getOrderStatus(reqGoToPay, responseEntity)) {
			return super.responseBeanToJson(responseEntity);
		}
		
		// 计算第三方支付金额和账户支付金额
		if (!this.getThirdPayAndAccountPay(reqGoToPay, responseEntity)) {
			return super.responseBeanToJson(responseEntity);
		}

		return super.responseBeanToJson(responseEntity);
	}

	/**
	 * @Description: 获取第三方支付金额和用户支付金额
	 * @author fengshuonan
	 * @return boolean 执行成功或失败
	 * @since 2.3.0
	 */
	private boolean getThirdPayAndAccountPay(ReqGoToPay reqGoToPay, ResponseEntity<ResGoToPay> responseEntity) {

		// 获取订单类型（1私家车 2出租车 3专车）
		Integer registrationType = reqGoToPay.getRegistrationType();

		// 获取账户余额
		BigDecimal account = responseEntity.getResponseBody().getCurrencyAmount();

		GetThirdPayAndAccountDto dto = this.processerFactory.getOrderProcesser(registrationType)
				.getThirdPayAndAccountPay(account, reqGoToPay.getOrderId());
		
		if(dto == null){
			responseEntity.setCode(GoToPayStatus.TOTAL_MONEY_IS_NULL.getCode());
			responseEntity.setErrorMessage(GoToPayStatus.TOTAL_MONEY_IS_NULL.getMessage());
			responseEntity.setPromptMessage(GoToPayStatus.TOTAL_MONEY_IS_NULL.getMessage());
			return false;
		}
		
		responseEntity.getResponseBody().setThirdPayMoney(dto.getThirdPayMoney());
		responseEntity.getResponseBody().setAccountPayMoney(dto.getAccountPayMoney());
		return true;
	}

	/**
	 * @Description: 获取订单状态
	 * @param orderType
	 *            订单类型 1：私家车 2：出租车 3:专车
	 * @param orderId
	 *            订单id
	 * @return boolean 执行成功或失败
	 * @author fengshuonan
	 * @since 2.3.0
	 */
	public boolean getOrderStatus(ReqGoToPay reqGoToPay, ResponseEntity<ResGoToPay> responseEntity) {

		int status = processerFactory.getOrderProcesser(reqGoToPay.getRegistrationType())
				.getOrderStatus(reqGoToPay.getOrderId());

		if (status == 0) {
			responseEntity.setCode(GoToPayStatus.ORDER_IS_NULL.getCode());
			responseEntity.setErrorMessage(GoToPayStatus.ORDER_IS_NULL.getMessage());
			responseEntity.setPromptMessage(GoToPayStatus.ORDER_IS_NULL.getMessage());
			return false;
		} else {
			responseEntity.getResponseBody().setOrderStatus(status);
			return true;
		}
	}

	/**
	 * @Description: 获取账户的余额
	 * @author fengshuonan
	 * @return boolean 执行成功或失败
	 * @since 2.3.0
	 */
	private boolean getUserAccountMoney(ReqGoToPay reqGoToPay, ResponseEntity<ResGoToPay> responseEntity) {

		String userId = reqGoToPay.getUserId();

		// 设置账户余额
		Useraccount useraccount = this.userAccountService.getUserAccount(userId);
		if (useraccount == null) {
			responseEntity.setCode(GoToPayStatus.USER_ACCOUNT_IS_NOT_EXIST.getCode());
			responseEntity.setErrorMessage(GoToPayStatus.USER_ACCOUNT_IS_NOT_EXIST.getMessage());
			responseEntity.setPromptMessage(GoToPayStatus.USER_ACCOUNT_IS_NOT_EXIST.getMessage());
			return false;
		} else {
			BigDecimal amount = useraccount.getCurrencyAmount();
			if (amount == null) {
				amount = new BigDecimal(0);
			}
			responseEntity.getResponseBody().setCurrencyAmount(amount);
			responseEntity.getResponseBody().setCurrencyAmountString(amount.toString());
		}

		// 设置用户积分
		Userintegral userintegral = this.userAccountService.getUserIntegral(userId);
		if (userintegral == null) {
			responseEntity.setCode(GoToPayStatus.USER_INTEGRAL_IS_NOT_EXIST.getCode());
			responseEntity.setErrorMessage(GoToPayStatus.USER_INTEGRAL_IS_NOT_EXIST.getMessage());
			responseEntity.setPromptMessage(GoToPayStatus.USER_INTEGRAL_IS_NOT_EXIST.getMessage());
			return false;
		} else {
			BigDecimal integral = userintegral.getUserIntegral();
			if (integral == null) {
				integral = new BigDecimal(0);
			}
			responseEntity.getResponseBody().setUserIntegral(integral);
			return true;
		}
	}
}
